package com.issac.demo.pooled2.mypool;

import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.pool2.ObjectPool;

import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

/**
 * @author: ywy
 * @date: 2023-06-28
 * @desc:
 */
@Slf4j
public class MyPool<T> {

    private Set<T> activeSet = Sets.newConcurrentHashSet(new HashSet<>());

    private Set<T> idleSet = Sets.newConcurrentHashSet(new HashSet<>());

    private int maxSize = 8;

    private Object lock = new Object();

    public MyPool(int maxSize) {
        this.maxSize = maxSize;
    }

    public synchronized T borrowObject(Class<T> clz) throws Exception {
        //
        T obj = null;
        // 1. 查看空闲单车
        if (idleSet.size() > 0) {
            obj = idleSet.iterator().next();
        }
        if (obj == null) {
            // 1. 数量上限判断
            int currentTotalSize = idleSet.size() + activeSet.size();
            if (currentTotalSize >= maxSize) {
                // 对象锁
                synchronized (lock) {
                    lock.wait();
                }
                return borrowObject(clz);
            }
            Method init = clz.getMethod("init");
            obj = (T) init.invoke(obj);
        } else {
            idleSet.remove(obj);
        }
        activeSet.add(obj);
        log.info("total size:{},active size:{},idle size:{}",
                idleSet.size() + activeSet.size(),activeSet.size(),
                idleSet.size());
        return obj;
    }

    public void returnObject(T obj) {
        if(obj != null) {
            idleSet.add(obj);
            activeSet.remove(obj);
            synchronized (lock) {
                lock.notify();
            }
        }
    }
}
